package edu.friday.service.impl;

import edu.friday.common.constant.UserConstants;
import edu.friday.common.result.TableDataInfo;
import edu.friday.model.SysRoleEntity;
import edu.friday.model.SysRoleMenuEntity;
import edu.friday.model.vo.SysRoleVo;
import edu.friday.repository.SysRoleMenuRepository;
import edu.friday.repository.SysRoleRepository;
import edu.friday.service.SysRoleService;
import edu.friday.common.utils.BeanUtils;
import edu.friday.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 角色表业务层
 */
@Service
public class SysRoleServiceImpl implements SysRoleService {

    @Autowired
    SysRoleRepository roleRepository;

    @Autowired
    SysRoleMenuRepository roleMenuRepository;

    @Override
    public TableDataInfo selectRoleList(SysRoleEntity user, Pageable page) {
        SysRoleEntity sysRole = new SysRoleEntity();
        BeanUtils.copyPropertiesIgnoreEmpty(user, sysRole);
        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withMatcher("roleName", ExampleMatcher.GenericPropertyMatchers.contains());
        Example<SysRoleEntity> example = Example.of(sysRole, exampleMatcher);
        Page<SysRoleEntity> rs = roleRepository.findAll(example, page);
        return TableDataInfo.success(rs.toList(), rs.getTotalElements());
    }

    @Override
    public String checkRoleNameUnique(String roleName) {
        SysRoleEntity sysRole = new SysRoleEntity();
        sysRole.setRoleName(roleName);
        return count(sysRole);
    }

    @Override
    @Transactional
    public boolean insertRole(SysRoleVo roleVo) {
        SysRoleEntity sysRole = new SysRoleEntity();
        BeanUtils.copyProperties(roleVo, sysRole);
        sysRole.setDelFlag("0");
        roleRepository.save(sysRole);
        roleVo.setRoleId(sysRole.getRoleId());
        for (int i = 0; i < roleVo.getMenuIds().length; i++) {
            roleMenuRepository.save(new SysRoleMenuEntity(roleVo.getRoleId(), roleVo.getMenuIds()[i]));
        }
        return null != sysRole.getRoleId();
    }

    /**
     * 查询所有角色
     *
     * @return 角色列表
     */
    @Override
    public List<SysRoleEntity> selectRoleAll() {
        return roleRepository.findAll();
    }

    /**
     * 根据用户Id获取角色选择框列表
     *
     * @param userId 用户Id
     * @return 选中角色Id列表
     */
    @Override
    public List<Long> selectRoleListByUserId(Long userId) {
        return roleRepository.selectRoleIdsByUserId(userId);
    }

    @Override
    public SysRoleEntity selectRoleById(Long roleId) {
        SysRoleEntity sysRole = new SysRoleEntity();
        sysRole.setRoleId(roleId);
        sysRole.setDelFlag("0");
        Optional<SysRoleEntity> one = roleRepository.findOne(Example.of(sysRole));
        return one.orElse(null);
    }

    @Override
    @Transactional
    public boolean updateRole(SysRoleVo roleVo) {
        Long roleId = roleVo.getRoleId();
        Optional<SysRoleEntity> op = roleRepository.findById(roleId);
        if (op.isEmpty()) return false;
        SysRoleEntity sysRole = op.get();
        sysRole.setStatus(roleVo.getStatus());
        roleRepository.save(sysRole);
        return null != sysRole.getRoleId();
    }

    /**
     * 根据用户ID查询权限
     *
     * @param userId 用户ID
     * @return 权限列表
     */
    @Override
    public Set<String> selectRolePermissionByUserId(Long userId) {
        List<SysRoleEntity> perms = roleRepository.selectRoleByUserId(userId);
        Set<String> permsSet = new HashSet<>();
        for (SysRoleEntity perm : perms) {
            if (StringUtils.isNotNull(perm)) {
                permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(",")));
            }
        }
        return permsSet;
    }

    private String count(SysRoleEntity sysRole) {
        Example<SysRoleEntity> example = Example.of(sysRole);
        long count = roleRepository.count(example);
        if (count > 0) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

}
